package middle.ground.utils;

import lombok.SneakyThrows;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 通用工具类
 *
 * @author jrl
 */
@SuppressWarnings("restriction")
public class CommonUtil {

	public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
			5,
			8,
			60,
			TimeUnit.SECONDS, new ArrayBlockingQueue<>(10)
			, new ThreadPoolExecutor.AbortPolicy()
	);

	/**
	 * zrx
	 *
	 * @param <K>
	 * @param restTemplate
	 * @param url
	 * @param body
	 * @param mediaType
	 * @param httpMethod
	 * @param token
	 * @param urlParams
	 * @param responses
	 * @param fileName
	 * @param isExport
	 * @return
	 */
	@SneakyThrows
	public static <K, V> V restRequest(RestTemplate restTemplate, String url, K body, Class<V> responseClass, MediaType mediaType, HttpMethod httpMethod, Map<String, String> headerMap,
									   Map<String, Object> urlParams, HttpServletResponse responses, String fileName, boolean isExport) {
		if (urlParams != null) {
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			StringBuilder urlBuilder = new StringBuilder(url);
			urlBuilder.append("?");
			for (Map.Entry<String, Object> entry : urlParams.entrySet()) {
				if (entry.getValue() != null) {
					if (entry.getValue() instanceof Date) {
						urlBuilder.append(entry.getKey()).append("=").append(URLEncoder.encode(dateFormat.format(entry.getValue()), "UTF-8")).append("&");
					} else {
						urlBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
					}
				}
			}
			url = urlBuilder.substring(0, urlBuilder.length() - 1);
		}
		HttpHeaders headers = new HttpHeaders();
		if (mediaType != null) {
			headers.setContentType(mediaType);
		}
		if (headerMap != null) {
			for (Map.Entry<String, String> entry : headerMap.entrySet()) {
				headers.add(entry.getKey(), entry.getValue());
			}
		}
		HttpEntity httpEntity = new HttpEntity<>(body, headers);
		if (isExport) {
			ResponseEntity<Resource> exchange = restTemplate.exchange(url, httpMethod, httpEntity, Resource.class);
			InputStream inputStream = Objects.requireNonNull(exchange.getBody()).getInputStream();
			responses.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
			BufferedOutputStream outputStream = new BufferedOutputStream(responses.getOutputStream());
			int len;
			byte[] buffer = new byte[1024];
			while ((len = inputStream.read(buffer)) != -1) {
				outputStream.write(buffer, 0, len);
			}
			outputStream.flush();
			outputStream.close();
			inputStream.close();
			return null;
		} else {
			ResponseEntity<V> exchange = restTemplate.exchange(url, httpMethod, httpEntity, responseClass);
			return exchange.getBody();
		}
	}
}
